package com.yorick.authority.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yorick.authority.entitys.*;
import com.yorick.authority.modal.request.role.*;
import com.yorick.authority.modal.response.BaseListResponse;
import com.yorick.authority.modal.response.role.RoleMenuResponse;
import com.yorick.authority.modal.response.role.RoleResponse;
import com.yorick.authority.service.AbstractAuthorityService;
import com.yorick.authority.service.RoleService;
import com.yorick.common.Result.SimpleFactory.ResultFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class RoleServiceImpl extends AbstractAuthorityService implements RoleService {

    @Override
    public BaseListResponse roleList(RoleListRequest request) {
        Integer currentPage = request.getCurrentPage();
        Integer pageSize = request.getPageSize();
        Integer start = (currentPage - 1) * pageSize;

        BaseListDto data = BaseListDto.builder()
                .start(start)
                .pageSize(pageSize)
                .superRole(request.isSuperRole())
                .keyword(request.getKeyword())
                .dids(getDID(request.getAid()))
                .build();

        BaseListResponse response = BaseListResponse.builder()
                .list(roleMapper.findRolesByDID(data))
                .total(roleMapper.roleTotal(data))
                .build();
        return response;
    }

    @Override
    public Map<String, Object> addRole(RoleAddRequest request) {
        RoleExternalDto roleExternalDto = RoleExternalDto.builder()
                .roleName(request.getRoleName())
                .roleDesc(request.getRoleDesc())
                .aid(request.getAid())
                .build();
        roleMapper.insertRole(roleExternalDto);

        //添加角色和机构的绑定
        insertRoleDepartment(getDID(request.getAid()), roleExternalDto.getRoleId());
        //添加角色和菜单的绑定
        insertRoleResource(request.getResourceId(), roleExternalDto.getRoleId());
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    public Map<String, Object> editRole(RoleEditRequest request) {
        RoleExternalDto roleExternalDto = RoleExternalDto.builder()
                .roleId(request.getRoleId())
                .roleName(request.getRoleName())
                .roleDesc(request.getRoleDesc())
                .enabled(request.getEnabled())
                .aid(request.getAid())
                .build();
        roleMapper.updateRole(roleExternalDto);

        //添加角色和菜单的绑定(先删除再插入)
        roleMapper.deleteResource(request.getRoleId());
        insertRoleResource(request.getResourceId(), roleExternalDto.getRoleId());
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    public RoleResponse roleDetail(RoleDetailRequest request) {
        RoleExternalDto role = roleMapper.findRoleByRoleID(request.getRoleId());
        List<ResourceDto> menus = roleMapper.findResourceByRoleID(request.getRoleId());
        Map<Integer, Node> nodes = new HashMap<>();
        for (int i = 0; i < menus.size(); i++) {
            ResourceDto resourceExternalDto = menus.get(i);
            //模拟数据库存储树结构
            Node node = Node.builder()
                    .id(resourceExternalDto.getResourceId())
                    .parentId(resourceExternalDto.getParentId())
                    .orderNum(resourceExternalDto.getOrderNum())
                    .name(resourceExternalDto.getResourceName())
                    .desc(resourceExternalDto.getResourceDesc())
                    .enabled(resourceExternalDto.getEnabled())
                    .build();
            nodes.put(resourceExternalDto.getResourceId(), node);

        }
        List<JSONObject> menu = getNodeJson(nodes);
        RoleResponse response = RoleResponse.builder()
                .roleId(role.getRoleId())
                .roleName(role.getRoleName())
                .roleDesc(role.getRoleDesc())
                .enabled(role.getEnabled())
                .aid(role.getAid())
                .opTime(role.getOpTime())
                .menus(sortList(menu))
                .build();
        return response;
    }

    @Override
    public Map<String, Object> deleteRole(RoleDeleteRequest request) {
        roleMapper.deleteRole(request.getRoleId());
        //清除mybatis缓存
        securityMapper.clearCache();
        return ResultFactory.success().display();
    }

    @Override
    protected JSONObject customizeNode(Node node) {
        RoleMenuResponse response = RoleMenuResponse.builder()
                .resourceId(node.getId())
                .resourceName(node.getName())
                .resourceDesc(node.getDesc())
                .orderNum(node.getOrderNum())
                .enabled(node.getEnabled())
                .build();
        return objectMapper.convertValue(response, JSONObject.class);
    }
}
